home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / machserver / 1.098 / fs / fsPageOps.c < prev    next >
C/C++ Source or Header  |  1991-06-27  |  9KB  |  289 lines

  1. /*
  2.  * fsPageOps.c --
  3.  *
  4.  *    The has the page-in, page-out, and page-copy routines used
  5.  *    by the VM system.
  6.  *
  7.  * Copyright 1987 Regents of the University of California
  8.  * All rights reserved.
  9.  * Permission to use, copy, modify, and distribute this
  10.  * software and its documentation for any purpose and without
  11.  * fee is hereby granted, provided that the above copyright
  12.  * notice appear in all copies.  The University of California
  13.  * makes no representations about the suitability of this
  14.  * software for any purpose.  It is provided "as is" without
  15.  * express or implied warranty.
  16.  */
  17.  
  18. #ifndef lint
  19. static char rcsid[] = "$Header: /sprite/src/kernel/fs/RCS/fsPageOps.c,v 1.10 91/06/27 12:11:05 mgbaker Exp $ SPRITE (Berkeley)";
  20. #endif not lint
  21.  
  22.  
  23. #include <sprite.h>
  24. #include <fs.h>
  25. #include <fsio.h>
  26. #include <fsutil.h>
  27. #include <fsNameOps.h>
  28. #include <fscache.h>
  29. #include <fsutilTrace.h>
  30. #include <fsStat.h>
  31. #include <fsdm.h>
  32. #include <fsprefix.h>
  33. #include <rpc.h>
  34. #include <vm.h>
  35. #include <fsrmt.h>
  36. #include <fslcl.h>
  37.  
  38. #include <stdio.h>
  39.  
  40.  
  41. /*
  42.  *----------------------------------------------------------------------
  43.  *
  44.  * Fs_PageRead --
  45.  *
  46.  *    Read in a virtual memory page.  This routine bypasses the cache.
  47.  *
  48.  * Results:
  49.  *    A return status, SUCCESS if successful.
  50.  *
  51.  * Side effects:
  52.  *    The page is filled with data read from the indicate offset.
  53.  *
  54.  *----------------------------------------------------------------------
  55.  */
  56. ReturnStatus
  57. Fs_PageRead(streamPtr, pageAddr, offset, numBytes, pageType)
  58.     Fs_Stream    *streamPtr;    /* Swap file stream. */
  59.     Address    pageAddr;    /* Pointer to page. */
  60.     int        offset;        /* Offset in file. */
  61.     int        numBytes;    /* Number of bytes in page. */
  62.     Fs_PageType    pageType;    /* CODE HEAP or SWAP */
  63. {
  64.     ReturnStatus        status = SUCCESS;
  65.     Fs_IOParam            io;    /* Write parameter block */
  66.     register Fs_IOParam        *ioPtr = &io;
  67.     Fs_IOReply            reply;    /* Return length, signal */
  68.     Boolean            retry;    /* Error retry flag */
  69.  
  70.     FsSetIOParam(ioPtr, pageAddr, numBytes, offset, 0);
  71.     reply.length = 0;
  72.     reply.flags = 0;
  73.     reply.signal = 0;
  74.     reply.code = 0;
  75.     /*
  76.      * We currently copy initialized
  77.      * HEAP pages into the cache.  Also, for non-SWAP
  78.      * pages a client should still check its cache to make sure it
  79.      * didn't just generate the data.
  80.      */
  81.     if ((pageType == FS_SWAP_PAGE) || (pageType == FS_SHARED_PAGE)) {
  82.     ioPtr->flags |= FS_SWAP;
  83.     } else if (pageType == FS_HEAP_PAGE) {
  84.     ioPtr->flags |= FS_HEAP;
  85.     } else if (pageType == FS_CODE_PAGE) {
  86.     ioPtr->flags &= ~(FS_SWAP | FS_HEAP);
  87.     }
  88.  
  89.     do {
  90.     retry = FALSE;
  91.     status = (fsio_StreamOpTable[streamPtr->ioHandlePtr->fileID.type].pageRead) (streamPtr, ioPtr, (Sync_RemoteWaiter *)NIL, &reply);
  92. #ifdef lint
  93.     status = Fsio_FileRead(streamPtr, ioPtr, (Sync_RemoteWaiter *)NIL, &reply);
  94.     status = FsrmtFilePageRead(streamPtr, ioPtr, (Sync_RemoteWaiter *)NIL, &reply);
  95.     status = FspdevPseudoStreamRead(streamPtr, ioPtr, (Sync_RemoteWaiter *)NIL, &reply);
  96.     status = Fsrmt_Read(streamPtr, ioPtr, (Sync_RemoteWaiter *)NIL, &reply);
  97. #endif /* lint */
  98.  
  99.     if (status == RPC_TIMEOUT || status == FS_STALE_HANDLE ||
  100.         status == RPC_SERVICE_DISABLED) {
  101.         /*
  102.          * The server is down so we wait for it.  This blocks
  103.          * the user process doing the page fault.
  104.          */
  105.         Net_HostPrint(streamPtr->ioHandlePtr->fileID.serverID,
  106.             "Fs_PageRead waiting\n");
  107.         status = Fsutil_WaitForRecovery(streamPtr->ioHandlePtr, status);
  108.         if (status == SUCCESS) {
  109.         retry = TRUE;
  110.         } else {
  111.         printf("Fs_PageRead recovery failed <%x>\n", status);
  112.         }
  113.     } else if (status == FS_WOULD_BLOCK) {
  114.         /*
  115.          * The remote server is so hosed that it can't
  116.          * deliver us a block.  There is no good way
  117.          * to wait.  Retry immediately?  Pound pound pound?
  118.          */
  119.         retry = TRUE;
  120.         printf("Fs_PageRead: blocked, waiting 1 min\n");
  121.         (void)Sync_WaitTime(time_OneMinute);
  122.     } else if (status != SUCCESS) {
  123.         printf("Fs_PageRead: Read failed <%x>\n", status);
  124.     }
  125.     } while (retry);
  126.  
  127.     return(status);
  128. }
  129.  
  130. /*
  131.  *----------------------------------------------------------------------
  132.  *
  133.  * Fs_PageWrite --
  134.  *
  135.  *    Write out a virtual memory page.  This is a simplified form of
  136.  *    Fs_Write that invokes the stream's pageWrite operation.  The
  137.  *    stream-specific procedure that is invoked can be the regular
  138.  *    write routine (as it is for local files)  or something more fancy
  139.  *    (as is true for remote files).  This passes the FS_SWAP flag down
  140.  *    to the pageWrite routine so a regular write routine can detect
  141.  *    the difference.
  142.  *
  143.  * Results:
  144.  *    A return status, SUCCESS if successful.
  145.  *
  146.  * Side effects:
  147.  *    The data in the buffer is written to the file at the indicated offset.
  148.  *
  149.  *----------------------------------------------------------------------
  150.  */
  151. ReturnStatus
  152. Fs_PageWrite(streamPtr, pageAddr, offset, numBytes, toDisk)
  153.     Fs_Stream    *streamPtr;    /* Swap file stream. */
  154.     Address    pageAddr;    /* Pointer to page. */
  155.     int        offset;        /* Offset in file. */
  156.     int        numBytes;    /* Number of bytes in page. */
  157.     Boolean    toDisk;        /* TRUE to write through to disk. */
  158. {
  159.     ReturnStatus        status = SUCCESS;
  160.     Fs_IOParam            io;    /* Write parameter block */
  161.     register Fs_IOParam        *ioPtr = &io;
  162.     Fs_IOReply            reply;    /* Return length, signal */
  163.  
  164.     FsSetIOParam(ioPtr, pageAddr, numBytes, offset, FS_SWAP |
  165.         (toDisk? FS_WRITE_TO_DISK : 0));
  166.     reply.length = 0;
  167.     reply.flags = 0;
  168.     reply.signal = 0;
  169.     reply.code = 0;
  170.  
  171.     status = (fsio_StreamOpTable[streamPtr->ioHandlePtr->fileID.type].pageWrite) (streamPtr, ioPtr, (Sync_RemoteWaiter *)NIL, &reply);
  172. #ifdef lint
  173.     status = Fsio_FileWrite(streamPtr, ioPtr, (Sync_RemoteWaiter *)NIL, &reply);
  174.     status = FsrmtFilePageWrite(streamPtr, ioPtr, (Sync_RemoteWaiter *)NIL, &reply);
  175.     status = FspdevPseudoStreamWrite(streamPtr, ioPtr, (Sync_RemoteWaiter *)NIL, &reply);
  176.     status = Fsrmt_Write(streamPtr, ioPtr, (Sync_RemoteWaiter *)NIL, &reply);
  177. #endif /* lint */
  178.  
  179.     return(status);
  180. }
  181.  
  182.  
  183. /*
  184.  *----------------------------------------------------------------------
  185.  *
  186.  * Fs_PageCopy --
  187.  *
  188.  *    Copy the file system blocks in the source swap file to the destination
  189.  *    swap file.  NOTE:  This is still specific to local and remote files.
  190.  *    This means that only Sprite files can be used for swap space.
  191.  *
  192.  * Results:
  193.  *    A return status, SUCCESS if successful.
  194.  *
  195.  * Side effects:
  196.  *    Appropriate blocks in the source file are copied to the dest file.
  197.  *
  198.  *----------------------------------------------------------------------
  199.  */
  200. ReturnStatus
  201. Fs_PageCopy(srcStreamPtr, destStreamPtr, offset, numBytes)
  202.     Fs_Stream    *srcStreamPtr;    /* File to copy blocks from. */
  203.     Fs_Stream    *destStreamPtr;    /* File to copy blocks to. */
  204.     int        offset;        /* Offset in file. */
  205.     int        numBytes;    /* Number of bytes in page. */
  206. {
  207.     int                lastBlock;
  208.     register    Fs_HandleHeader    *srcHdrPtr;
  209.     register    Fs_HandleHeader    *destHdrPtr;
  210.     ReturnStatus        status = SUCCESS;
  211.     int                i;
  212.     Boolean            retry;
  213.     Address            swapPageCopy = (Address) NIL;
  214.     Boolean            swapPageAllocated = FALSE;
  215.  
  216.     srcHdrPtr = srcStreamPtr->ioHandlePtr;
  217.     destHdrPtr = destStreamPtr->ioHandlePtr;
  218.     lastBlock = (unsigned int) (offset + numBytes - 1) / FS_BLOCK_SIZE;
  219.  
  220.     /*
  221.      * Copy all blocks in the page.
  222.      */
  223.     for (i = (unsigned int) offset / FS_BLOCK_SIZE; i <= lastBlock; i++) {
  224.     do {
  225.         retry = FALSE;
  226.         if (srcHdrPtr->fileID.serverID != destHdrPtr->fileID.serverID) {
  227.         /*
  228.          * The swap files are on different machines, so we need to read
  229.          * from one and write to the other.
  230.          */
  231.         if (!swapPageAllocated) {
  232.             swapPageCopy = (Address) malloc(Vm_GetPageSize());
  233.         }
  234.         swapPageAllocated = TRUE;
  235.         status =
  236.             Fs_PageRead(srcStreamPtr, swapPageCopy, offset,
  237.             numBytes, FS_SWAP_PAGE);
  238.         if (status != SUCCESS) {
  239.             /* Fs_PageRead handles recovery itself, so we don't here. */
  240.             break;
  241.         }
  242.         status =
  243.             Fs_PageWrite(destStreamPtr, swapPageCopy, offset,
  244.             numBytes, TRUE);
  245.         } else {
  246.         status = (fsio_StreamOpTable[srcHdrPtr->fileID.type].blockCopy)
  247.             (srcHdrPtr, destHdrPtr, i);
  248. #ifdef lint
  249.         status = Fsio_FileBlockCopy(srcHdrPtr, destHdrPtr, i);
  250.         status = Fsrmt_BlockCopy(srcHdrPtr, destHdrPtr, i);
  251. #endif /* lint */
  252.         }
  253.         if (status != SUCCESS) {
  254.         if (status == RPC_TIMEOUT || status == RPC_SERVICE_DISABLED ||
  255.             status == FS_STALE_HANDLE) {
  256.             /*
  257.              * The server is down so we wait for it.  This just blocks
  258.              * the user process doing the page fault.
  259.              */
  260.             Net_HostPrint(srcHdrPtr->fileID.serverID,
  261.                 "Fs_PageCopy waiting for recovery\n");
  262.             status = Fsutil_WaitForRecovery(srcStreamPtr->ioHandlePtr,
  263.                 status);
  264.             if (status == SUCCESS) {
  265.             retry = TRUE;
  266.             } else {
  267.             printf("Fs_PageCopy, recovery failed <%x>\n", status);
  268.             if (swapPageAllocated) {
  269.                 free(swapPageCopy);
  270.             }
  271.             return(status);
  272.             }
  273.         } else {
  274.             printf("Fs_PageCopy: Copy failed <%x>\n", status);
  275.             if (swapPageAllocated) {
  276.             free(swapPageCopy);
  277.             }
  278.             return(status);
  279.         }
  280.         }
  281.     } while (retry);
  282.  
  283.     }
  284.     if (swapPageAllocated) {
  285.     free(swapPageCopy);
  286.     }
  287.     return(status);
  288. }
  289.